<template>
  <div class="card-container">
    <div ref="card" :style="{ width: width + 'px', height: height + 'px'}" class="card" id="card">
      <!-- 渐变 -->
      <div ref="cardShine" class="card-shine"></div>
      <!-- 阴影 -->
      <div ref="cardShadow" class="card-shadow"></div>
      <!-- 图片 -->
      <div ref="cardLayer" class="card-layer">
        <img :src="src" alt="">
      </div>
    </div>
  </div>
</template>

<script>
const sizemap = {
  large: 1169,
  normal: 800,
  small: 400
}
export default {
  props: {
    src: {
      type: String,
      default: 'https://p.sda1.dev/22/244af35b5ba137349f14fd08b80d0f97/img_staff_tokuoka.jpg'
    },
    size: {
      type: String,
      default: 'large'
    }
  },
  computed: {
    height() {
      return sizemap[this.size]
    },
    width() {
      return this.height / 1.4
    }
  },
  data() {
    return {
      movelimit: null,
      card: null,
      shadow: null,
      shine: null,
    }
  },
  methods: {
    spinCard() {
      this.movelimit.addEventListener('mousemove', e => {
        window.requestAnimationFrame(() => {
          this.moveCard(e.clientX, e.clientY)
        })
      })
      this.movelimit.addEventListener('mouseleave', () => {
        window.requestAnimationFrame(() => {
          this.card.style.transform = `rotateX(0deg) rotateY(0deg)`
        })
      })
    },
    moveCard(clientX, clientY) {
      let { x, y, width, height } = this.card.getBoundingClientRect()
      // (width/2, height/2) 是卡片的中心 -> 卡片翻转的偏移量
      let calX = +(clientX - x - width / 2)
      let calY = -(clientY - y - height / 2)
      // shine deg
      let shineDeg = -Math.atan2(calY, calX) * 180 / Math.PI

      // 灵敏系数: 防止卡片偏移量不够
      const sensitivity = 2000 / height
      this.card.style.transform = `rotateX(${calY / (100 / sensitivity)}deg) rotateY(${calX / (100 / sensitivity)}deg)`
      this.shadow.style.boxShadow = `${calX / 50}px ${calY / 50}px 20px 8px rgba(0, 0, 0, 0.7)`
      this.shine.style.background = `linear-gradient(${shineDeg}deg, rgba(255, 255, 255, 0) 20%, rgba(240, 240, 240, 0.5) 100%)`
    }
  },
  mounted() {
    this.movelimit = this.$refs.card
    this.card = this.$refs.card
    this.shadow = this.$refs.cardShadow
    this.shine = this.$refs.cardShine
    this.spinCard()
  }
}
</script>

<style scoped lang="less">
.card-container {
  transform-style: preserve-3d; // 开启3d空间
  perspective: 1200px; // 透视距离
}

[class^="card"] {
  transform-style: preserve-3d;
  cursor: pointer;
  transition: all cubic-bezier(0.19, 1, 0.22, 1) .8s;
}
// card: 
.card {
  // height: 1169px;
  // width: 826px;
  margin: 0 auto;
  transform: rotateX(-6deg);
  position: relative;
  cursor: pointer;
  border-radius: 20px;
  overflow: hidden;

  .card-shine {
    position: absolute;
    top: 0px;
    bottom: 0px;
    right: 0px;
    left: 0px;
    border: 4px solid #ffe51e;
    border-radius: 20px;
    background: linear-gradient(0deg, rgba(240, 240, 240, 0) 20%, rgba(240, 240, 240, 0.5) 100%);
    z-index: 99;
  }

  .card-shadow {
    position: absolute;
    top: 5%;
    left: 5%;
    width: 90%;
    height: 90%;
    box-shadow: 0px 8px 20px 5px rgba(0, 0, 0, 0.7);
    border-radius: 20px;
    z-index: 1000;
  }

  .card-layer {
    width: 100%;
    height: 100%;
    // background-image: url('~@/assets/404.jpg') !important;
    // background-size: cover !important;
    overflow: hidden;
    z-index: -1;
    img {
      width: inherit;
      height: inherit;
      object-fit: cover;
    }
  }
}
</style>